#!/usr/bin/env python
# encoding: utf-8
"""
Shovelhead
File: MyFrame.py
Author: Myriam Boucher

GUI
"""

from pyo import *
from Environment import *
from Gear import *
from Engine import *
from Shovelhead import *
from VTwin import *
from Panhead import *
import wx, os
import math
from pyolib._wxwidgets import VuMeter, ControlSlider, BACKGROUND_COLOUR

class MyFrame(wx.Frame):
    def __init__(self, parent, title, pos, size, serveur, obj):
        wx.Frame.__init__(self, parent, id=-1, title=title, pos=pos, size=size)
        self.panel = wx.Panel(self)
        self.panel.SetBackgroundColour("#C0C0C0")
        self.engine = None 
        self.rock = obj
        self.serveur = serveur
        self.rev = None

        self.serveur.start()
        
        # Menu.
        menubar = wx.MenuBar()
        fileMenu = wx.Menu()
        fileMenu.Append(wx.ID_EXIT, "Quit\tCtrl+Q")
        menubar.Append(fileMenu, "File")
        self.SetMenuBar(menubar)
        self.Bind(wx.EVT_MENU, self.onQuit, id=wx.ID_EXIT)
        self.Bind(wx.EVT_CLOSE, self.onQuit)
        
        # Titre.
        self.titreText = wx.StaticText(self.panel, id=-1, label='HARLEY-DAVIDSON BOX', pos=(320,10), size = wx.DefaultSize)
        
        # Kickstart button.
        self.starting = wx.Button(self.panel, id=-1, label='Kickstart', pos=(20,75), size = wx.DefaultSize)
        self.starting.Bind(wx.EVT_BUTTON, self.kickstart)
    
        # Run button.
        self.running = wx.Button(self.panel, id=-1, label='Run', pos=(20,110), size = wx.DefaultSize)
        self.running.Bind(wx.EVT_BUTTON, self.runEngine)
        
        # Shift Gears button.
        self.shiftingGears = wx.Button(self.panel, id=-1, label='Shift Gear', pos=(20,145), size = wx.DefaultSize)
        self.shiftingGears.Bind(wx.EVT_BUTTON, self.shiftGears)
        
        # Stop button.
        self.stoping = wx.Button(self.panel, id=-1, label='Stop', pos=(20,180), size = wx.DefaultSize)
        self.stoping.Bind(wx.EVT_BUTTON, self.stopEngine)
        
        # Motorcycle choices.
        self.typesEngine = ['Shovelhead', 'V-Twin', 'Panhead']
        self.typesText = wx.StaticText(self.panel, id=-1, label='Choose a Motorcycle...', pos=(150,75), size = wx.DefaultSize)
        self.typesChoice = wx.Choice(self.panel, id=-1, pos = (148,95), size=wx.DefaultSize, choices = self.typesEngine) 
        self.typesChoice.Bind(wx.EVT_CHOICE, self.setTypeEngine)
        
        # Drop-down list to choose the environment (reverb).
        self.reverbTypes = ['garage', 'church', 'no environment']
        self.reverbText = wx.StaticText(self.panel, id=-1, label='Choose an environment...', pos=(150,145), size = wx.DefaultSize)
        self.reverbChoice = wx.Choice(self.panel, id=-1, pos = (148,165), size=wx.DefaultSize, choices = self.reverbTypes) 
        self.reverbChoice.Bind(wx.EVT_CHOICE, self.setEnvironment)
        
        # Rock On! button (motorcycle radio).
        self.bmp = wx.Image("speaker.bmp", wx.BITMAP_TYPE_BMP).ConvertToBitmap()
        self.rockingOn = wx.BitmapButton(self.panel, id=-1, bitmap=self.bmp, pos=(330,175), style=0)
        self.rockingOn.Bind(wx.EVT_BUTTON, self.rockOnMusic, self.rockingOn)
        self.rockingOn.SetDefault()
        
        # Stop Rock On! music button.
        self.rockingOff = wx.Button(self.panel, id=-1, label='Stop it!', pos=(350,285), size = wx.DefaultSize)
        self.rockingOff.Bind(wx.EVT_BUTTON, self.rockOffMusic)
        
        # Control the overall volume with a slider.
        self.ampText = wx.StaticText(self.panel, id=-1, label="Volume", pos=(25,230), size = wx.DefaultSize)
        self.amp = wx.Slider(self.panel, id=-1, value = 500, minValue=0, maxValue=1000, pos=(10,245), size=(250,-1))
        self.amp.Bind(wx.EVT_SLIDER, self.changeAmp) 
        
        # Control the pan with a slider.
        self.panText = wx.StaticText(self.panel, id=-1, label="Pan", pos=(25,270), size=wx.DefaultSize)
        self.pan = wx.Slider(self.panel, id=-1, value = 500, minValue=0, maxValue=1000, pos=(10,285), size=(250,-1))
        self.pan.Bind(wx.EVT_SLIDER, self.changePan) 
    
    def onQuit(self, evt):
        # the user exits the program.
        self.stopEngine(evt)
        self.closeServeur()
        self.Destroy()
        
    def closeServeur(self):
        # stop the server.
        if self.serveur.getIsStarted():
            self.serveur.stop()
        
    def changePan(self, evt):
        # change the pan.
        if self.engine != None:
            x = evt.GetInt()*.001
            self.panText.SetLabel("Pan : %.3f" %x)
            self.engine.panSpatialization(x)
        
    def setTypeEngine(self, evt):
        # choice of the motorcycle.
        if self.engine != None:
                self.stopEngine(evt)
                #self.engine.stopSound()
        if evt.GetString()=='Shovelhead':
            self.panel.SetBackgroundColour("#DAA520")
            self.engine = Shovelhead()
        elif evt.GetString()=='V-Twin':
            self.panel.SetBackgroundColour("#FF1493")
            self.engine = VTwin()
        else:
            self.panel.SetBackgroundColour("#40E0D0")
            self.engine = Panhead()
        self.Refresh()
        
        
    def setEnvironment(self, evt):
        # choice of the environment.
        if evt.GetString()=='no environment':
            self.engine.stopSound()
            self.rev.stopReverb()
            #self.engine.outEngine()
        else:
            self.engine.stopSound()
            self.rev = Environment(evt.GetString(), self.engine)
            self.rev.outReverb()
        
    def changeAmp(self, evt):
        # amplitude change.
        x = evt.GetInt()*.001
        i = evt.GetInt()*.1
        self.ampText.SetLabel("Volume : %d" %i)
        self.serveur.amp = x
        
    def kickstart(self, evt):
        # kickstart of the engine.
        if self.engine != None:
            self.engine.stopSound()
            self.engine.kickStartEngine()
        else:
            print "Choice a motorcycle!"
        
    def runEngine(self, evt):
        # the engine running.
        if self.engine != None:
            self.engine.outEngine()
            if isinstance(self.engine, Shovelhead):
                self.engine.playShovelhead()
            elif isinstance(self.engine, VTwin):
                self.engine.playVTwin()
            else:
                self.engine.playPanhead()
        else:
            print "Choice a motorcycle!"
      
    def stopEngine(self, evt):
        # stop the audio engine objects.
        if self.engine != None:
            self.engine.stopSound()
            self.engine.getGearEngine().stopExpSpeed()  
            if isinstance(self.engine,Shovelhead):
                self.engine.stopShovelhead()
            elif isinstance(self.engine, VTwin):
                self.engine.stopVTwin()
            else:
                self.engine.stopPanhead()
        else:
            print "Choice a motorcycle!"   
        
    def shiftGears(self, evt):
        # gear shift.
        if self.engine != None:
            a = self.engine.getGearEngine()
            a.shift()
        else:
            print "Choice a motorcycle!"
        
    def rockOnMusic(self, evt):
        # plays background music.
        self.rock.playMusic()
    
    def rockOffMusic(self, evt):
        # stop background music.
        self.rock.stopMusic()

